<template>
  <div class="flat-date-picker">
    <FlatPickr
      v-model="data"
      :config="config"
      placeholder="请选择时间"
      @on-open="createTimeSorter"
      @on-change="onChange"
    />
    <span data-toggle="" class="picker-icon picker-time"></span>
  </div>
</template>

<script>
import FlatPickr from 'vue-flatpickr-component'
import 'flatpickr/dist/l10n/zh'
import 'flatpickr/dist/flatpickr.css'
import moment from 'moment'
/** 插件文档 https://flatpickr.js.org/ */

export default {
  name: 'FlatDateTimePicker',
  components: {
    FlatPickr
  },
  props: {
    /** 值 */
    value: String,
    /** 最小时间 */
    minDate: Date | String,
    /** 最大时间 */
    maxDate: Date | String,
    dataId: String,
    exceedsUpdDate: {
      type: Boolean,
      default: false
    }
  },
  model: {
    prop: 'value',
    event: 'update'
  },
  watch: {
    value: {
      handler(val) {
        const nVal = val ? moment(val).format('YYYY-MM-DD HH:mm:ss') : undefined
        if (nVal !== this.data) {
          this.data = nVal
        }
      },
      immediate: true
    },
    minDate: {
      handler(val) {
        this.config.minDate = val ?  new Date(moment(val).format('YYYY-MM-DD HH:mm:00')): null
        if (
          moment(this.data).isBefore(moment(this.config.minDate).format('YYYY-MM-DD HH:mm:ss')) &&
          this.exceedsUpdDate
        ) {
          this.$emit('update', undefined)
        }
      },
      immediate: true
    },
    maxDate: {
      handler(val) {
        this.config.maxDate = val ?  new Date(moment(val).format('YYYY-MM-DD HH:mm:59')): null
        if (
          moment(this.data).isAfter(moment(this.config.maxDate).format('YYYY-MM-DD HH:mm:ss')) &&
          this.exceedsUpdDate
        ) {
          this.$emit('update', undefined)
        }
      },
      immediate: true
    }
  },
  data: () => ({
    data: '',
    config: {
      defaultDate: '',
      enableTime: true,
      time_24hr: true,
      allowInput: false,
      allowInvalidPreload: false,
      minDate: null,
      maxDate: null,
      dateFormat: 'Y-m-d H:i',
      locale: 'zh',
      altInputClass: 'picker-input'
    },
    updateVal: ''
  }),
  methods: {
    moment,
    onChange(selectedDates, dateStr, instance) {
      this.$emit('update', dateStr ? moment(dateStr).format('YYYY-MM-DD HH:mm:ss') : dateStr)
    },
    createTimeSorter(e, t, n) {
      const $container = $(n.innerContainer)
      $(n.calendarContainer).addClass('flatpickr-calendar--notime')
      const dateObj = moment(t)
      const h = dateObj.hours()
      const m = dateObj.minutes()
      const timeDomLength = $container.find('.flatpickr-rContainer--time').length
      let l = 0
      m >= 30 && (l = 30)
      if (timeDomLength > 0) {
        const timeDom = $container.find('.js-flatpickr-rContainer--time')
        const hourDom = timeDom.find(".flatpickr-day[data-hour='" + this.digitalSplicing(h) + "']")
        const dayDom = timeDom.find('.flatpickr-day')
        dayDom.siblings().removeClass('active')
        let dataMinute = $(hourDom[0]).data('minute')
        let dataHour = $(hourDom[1])
        String(dataMinute) === String(l) && (dataHour = $(hourDom[1]))
        dataHour.addClass('active')
        return this.scrollTop($container, dayDom.index(dataHour))
      }

      const dateTimeDom = $(this.createDateTimeDom())
      for (var index = 0, hour = 0, minute = 0; index < 48; index++) {
        hour = this.digitalSplicing(hour)
        minute = this.digitalSplicing(minute)
        let isActive = h === Number(hour) && l === Number(minute)
        if (isActive) {
          ;(i => {
            setTimeout(() => {
              this.scrollTop($container, i)
            }, 0)
          })(index)
        }
        const timeDom = $(
          this.createTimeDom({
            isActive,
            hour,
            minute
          })
        )
        minute === 30 ? ((minute = 0), hour++) : (minute = 30)

        dateTimeDom.find('.dayContainer').append(timeDom)
      }
      dateTimeDom.find('.flatpickr-day').on('click', e => {
        const _this = $(e.target)
        let text = _this.text()
        let date = n.formatDate(n.selectedDates[0], 'Y-m-d')
        let selectedTime = date + ' ' + text
        if (n.config.minDate && moment(date + ' ' + text).valueOf() <= moment(n.config.minDate).valueOf()) return false
        n.setDate(selectedTime, true)
        _this.siblings().removeClass('active')
        _this.addClass('active')
        n.close()
      })
      $container.append(dateTimeDom)
    },
    scrollTop(e, t) {
      $(e)
        .find('.js-flatpickr-rContainer--time .dayContainer')
        .scrollTop(40 * t - 50)
    },
    createDateTimeDom() {
      return `<div class=" flatpickr-rContainer flatpickr-rContainer--time js-flatpickr-rContainer--time">
      <div class="flatpickr-weekdays">
        <span class="flatpickr-weekday">时间</span>
      </div>
      <div class="flatpickr-days" tabindex="-1" >
        <div class="dayContainer"></div>
      </div>
    </div>`
    },
    createTimeDom(options) {
      const { isActive, hour, minute } = options
      return `<span class="flatpickr-day ${
        isActive ? 'active' : ''
      }" tabindex="-1" data-hour="${hour}" data-minute="${minute}">${hour}:${minute}</span>`
    },
    digitalSplicing(num) {
      return num.toString().length < 2 ? '0' + num : num
    }
  }
}
</script>

<style lang="less">
@import './index.less';
</style>
